import re

from loguru import logger

from api_test_framework.data.envi_data import EnviData
from api_test_framework.utils.handle_gendata import GenData

def replace_mark_data(str_data):
    """
    替换数据中的变量标记
    :param str_data: 要替换的数据
    :return: 替换后的数据
    """
    if str_data is None:
        logger.info("数据为空，不需要替换操作！")
        return

    mark_list = re.findall("#(.*?)#", str_data)
    logger.info(f"正则查询的结果是：{mark_list}")

    if mark_list:
        logger.info("================开始替换数据===================")
        logger.info(f"原始字符串是：{str_data}")

        for mark in mark_list:
            # 对mark_data进行判断：是否有()，有的话就是调用生成数据的方法并替换mark数据，没有就是直接替换环境变量的数据
            if "()" in mark:
                # mark_data 用正则匹配出来之后是个字符传，所以要跟类前缀拼接 -格式化输出拼接完整实例方法的调用
                # 字符串包裹的一个实例方法调用，使用eval执行字符串里的python表达式
                gen_data = eval(f'GenData().{mark}')  # 例如：GenData().gen_unregister_phone()
                fun_name = mark.strip("()")  # 得到属性名，例如: gen_unregister_phone
                setattr(EnviData, fun_name, gen_data)
                logger.info(f"设置生成数据到环境变量后：{EnviData.__dict__}")
                # 替换原來的数据 -- 函数构造生成数据结果替换占位符的数据
                str_data = str_data.replace(f"#{mark}#", str(gen_data))
            else:
                if hasattr(EnviData, mark):
                    value = getattr(EnviData, mark)
                    str_data = str_data.replace(f"#{mark}#", str(value))
    else:
        logger.info("没有要替换的数据")

    logger.info(f"替换完成之后的字符串是：{str_data}")
    return str_data


if __name__ == '__main__':
    # 假设已经从前面的接口提取并存到环境变量的数据
    class EnviData:
        prodId = 123
        skuId = 456


    # mark_data = '{"basketId": 0, "count": 1, "prodId": #prodId#, "shopId": 1, "skuId": #skuId#}'
    mark_data = '{"mobile":"#gen_unregister_phone()#"}'
    print(replace_mark_data(mark_data))
